package com.user.application.command.service;

import com.common.aes.EncoderUtil;
import com.common.result.Result;
import com.event.DomainEvent;
import com.event.DomainEventPublisher;
import com.oss.client.OssClient;
import com.oss.config.OssProperties;
import com.security.service.AuthenticateService;
import com.user.application.command.cmd.UserCommand;
import com.user.domain.entity.User;
import com.user.domain.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

import static com.user.domain.event.UserEventEnum.*;
import static com.user.domain.factory.UserFactory.USER_CONVERT;


/**
 * @author 大忽悠
 * @create 2022/9/15 21:34
 */
@Service
@RequiredArgsConstructor
@Transactional
public class UserCommandService {
    private final UserRepository userRepository;
    private final DomainEventPublisher eventPublisher;
    private final OssClient ossClient;
    private final OssProperties ossProperties;
    private final AuthenticateService authenticateService;

    /**
     * 登录: 利用openFeign向认证中心发送登录请求,从而获取token
     */
    public String login(String username,String password){
        Integer uid = User.loginVerify(username, EncoderUtil.decodeWithPrefixOrEncode(password), userRepository);
        Result token = authenticateService.generatorToken(uid, username);
        publishDomainEvent(uid,USER_LOGIN_EVENT.getEventType());
        return (String) token.getData();
    }

    /**
     * 注册用户,注册成功后,返回新用户的ID<p>
     * 如果用户没有设置头像,那么默认随机生成一个头像<p>
     * 如果用户设置了头像,就使用用户上传的头像<P>
     * 将头像上传至OSS
     */
    public Integer registerUser(UserCommand userCommand) throws IOException {
        User user = USER_CONVERT.toUser(userCommand);
        user.safeCheck(userRepository);
        user.uploadHeadImg(ossClient,ossProperties.getEndpoint()+"/"+ossProperties.getBucketName()+"/",userCommand.getHeadImgFile());
        user.setId(userRepository.registerUser(user));
        publishDomainEvent(user,USER_INSERT_EVENT.getEventType());
        return user.getId();
    }

    /**
     * 更新用户信息
     */
    public void updateUserInfo(UserCommand userCommand){
        User user = USER_CONVERT.toUser(userCommand);
        userRepository.updateUserInfo(user);
        publishDomainEvent(user,USER_UPDATE_EVENT.getEventType());
    }

    /**
     * 删除用户
     */
    public void deleteUser(Integer id){
        userRepository.deleteUser(id);
        publishDomainEvent(id,USER_DELETE_EVENT.getEventType());
    }

    /**
     * 发布领域事件
     */
    private void publishDomainEvent(Object info,Integer eventType){
        eventPublisher.publishEvent(new DomainEvent(info,USER_DOMAIN, eventType));
    }
}
